/*
 *Copyright(c) 2013, SiChuan ChangHong Multimedia Crop.
 *ALL rights reserved.
 *
 *Filename : 	AQadjust.java
 *Abstract :    Describe the content of this file summarily
 *Android SDK version	:	4.03
 *Create Date					:	NOV 12,2012
 *Version						:	1.0
 *Author						:	qinglin.wu
 *Accomplished date		:	May 17,2013
 */
package com.homwee.factory.tvtool;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Properties;

import android.util.Log;

public class INIFile {
	// openINI()
	// getValue()
	// setValue()
	// closeINI()
	public static final String TAG = "FileINI";
	protected HashMap sections = new LinkedHashMap(); // LinkedHashMap(512,1,false)
	// protected Map keyMap = new TreeMap();
	protected HashMap myMap = new LinkedHashMap();
	private String currentSecion = "null";
	private Properties current;
	private String fileName = null;
	private String Module = null;
	private String Identifier = null;

	public INIFile(String argModule, String argIdentifier) {
		Module = argModule;
		Identifier = argIdentifier;

	}

	/*
	 * Description: read the data from file. Parameter: the file name. Return:
	 * the read line number. return zero if f ile not found or empty.
	 */
	public int openINI(String argFileName) {
		int read_line = 0;
		if (fileName != null) {
			return read_line;
		}
		fileName = argFileName;
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(argFileName), "UTF-8"));
			String line;
			while ((line = reader.readLine()) != null) {
				read_line++;
				parseINILine(line);
			}
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
			Log.v(TAG, "INIReader: read error.");
		}
		return read_line;
	}

	/*
	 * Description: parse one line which read from file. Parameter: the line.
	 * Return: NONE.
	 */
	protected int parseINILine(String line) {
		line = line.trim();
		if (line.startsWith("#", 0)) // Annotations are not parsed
			return 0;
		int k = -1;
		if ((k = line.indexOf(';')) > 0)// The comment behind the semicolon is the comment，Give up
			line = line.substring(0, k);

		if (line.matches("\\[.*\\]")) {
			currentSecion = line.replaceFirst("\\[(.*)\\]", "$1");
			current = new Properties();
		} else if (line.matches(".*=.*")) {
			int i = line.indexOf('=');
			String name = line.substring(0, i);
			String value = line.substring(i + 1);
			current.setProperty(name.trim(), value.trim());
			sections.put(currentSecion, current);

			myMap.put((currentSecion + name).trim(), currentSecion.trim());
		}
		return 1;
	}

	/*
	 * Description: get value by section and key. Parameter: section and key.
	 * Return: the value. return null if not found.
	 */
	public String GetValue(String section, String key) {
		if (fileName == null) {
			return null;
		}
		Properties p = (Properties) sections.get(section);
		if (p == null) {
			return null;
		}
		String value = "";
		value = p.getProperty(key);
		// Log.d("EncryptBox", "get value="+value);
		return value;
	}

	/*
	 * Description: update value. Parameter: section, key and value. add it if
	 * the section not exist; change the value of key if the section exist.
	 * Return: true: change success, false: change fail. Notice: we don't write
	 * data into file in this function.
	 */

	public boolean SetValue(String sectionName, String key, String value) {
		if (key.length() == 0) {
			return false;
		}
		sectionName = sectionName.trim();
		Properties p = (Properties) sections.get(sectionName);
		if (null == p) {
			// not find the section, we should create it.
			current = new Properties();
			current.setProperty(key.trim(), value.trim());
			sections.put(sectionName, current);

			myMap.put((sectionName + key).trim(), sectionName);

			return true;

		}
		p.setProperty(key, value);

		myMap.put((sectionName + key).trim(), sectionName);

		return true;
	}

	/*
	 * Description: write the data to file. Parameter: NONE. Return: true:
	 * success.
	 */
	public boolean closeINI(String argFileName) {
		Log.v(TAG, "update ini file??????????");
		return writeBack(argFileName);
	}

	private boolean writeBack(String argFileName) {
		if (argFileName == null) {
			return false;
		}
		PrintWriter writer = null;
		try {
			Log.v("INIFile", "1");
			File f = new File(argFileName);
			Log.v("INIFile", "a");
			if (!f.exists()) {
				// create file.
				Log.v("INIFile", "b");
				f.createNewFile();
				Log.v("INIFile", "c");
			}
			Log.v("INIFile", "2");
			writer = new PrintWriter(new OutputStreamWriter(
					new FileOutputStream(f)));
			StringBuilder builder = new StringBuilder();
			Iterator<String> iterator = sections.keySet().iterator();
			Log.v("INIFile", "3");
			while (iterator.hasNext()) {
				String sectionName = iterator.next();
				Properties p = (Properties) sections.get(sectionName);
				builder.append("\n").append("\n\n").append("[")
						.append(sectionName).append("]");
				builder.append(getPropertiesOrder(p, sectionName));
			}
			Log.v("INIFile", "4");
			String strHeader = buildIniFileHeader();
			Log.v("INIFile", "5");
			writer.write(strHeader.toString());
			Log.v("INIFile", "6");
			writer.write(builder.toString().trim());
			Log.v("INIFile", "7");
			writer.flush();
			writer.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			Log.e("EncryptBox", "INIReader: write error(" + argFileName + ").");
		}
		if (writer != null) {
			writer.close();
		}
		return false;
	}

	/*
	 * Description: get the string of Properties. Parameter: Properties. Return:
	 * string.
	 */
	private String getPropertiesString(Properties p) {
		StringBuilder builder = new StringBuilder();
		Iterator iterator = p.entrySet().iterator(); // entrySet //keySet
		while (iterator.hasNext()) {
			// String key = iterator.next().toString();
			Entry e = (Entry) iterator.next();
			// builder.append("\n").append(key).append("=").append(p.get(key));
			builder.append("\n").append(e.getKey().toString()).append("=")
					.append(e.getValue().toString());
		}
		return builder.toString();
	}

	private String getPropertiesAll(Properties p, String sectionName) {

		StringBuilder builder = new StringBuilder();
		Iterator iterator = myMap.entrySet().iterator();
		while (iterator.hasNext()) {

			Entry e = (Entry) iterator.next();
			if (e.getValue().equals(sectionName)) {

				// builder.append("\n").append(e.getKey().toString()).append("=").append(e.getValue().toString());
				builder.append("\n").append(e.getKey().toString()).append("=")
						.append(p.get(e.getKey().toString()));
			}
		}

		return builder.toString();
	}

	private String getPropertiesOrder(Properties p, String sectionName) {

		StringBuilder builder = new StringBuilder();
		Iterator iterator = myMap.entrySet().iterator();
		String strTemp = "";
		while (iterator.hasNext()) {

			Entry e = (Entry) iterator.next();
			if (e.getValue().equals(sectionName)) {
				if (e.getKey().toString().startsWith(sectionName.trim())) {
					strTemp = e.getKey().toString();
					strTemp = strTemp.replaceFirst(sectionName.trim(), "");
				}
				// builder.append("\n").append(e.getKey().toString()).append("=").append(e.getValue().toString());
				builder.append("\n").append(strTemp.trim()).append("=")
						.append(p.get(strTemp.trim()));
			}
		}

		return builder.toString();
	}

	private String buildIniFileHeader() {
		String strHeader = null;
		//Date now = new Date();
		//DateFormat d1 = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
		//		DateFormat.MEDIUM);
		//String strTime = d1.format(now);
		
		SimpleDateFormat    sDateFormat    =   new    SimpleDateFormat("yyyy-MM-dd    hh:mm:ss");   
		String    strTime    =    sDateFormat.format(new    java.util.Date()); 

		strHeader = "#############################################################\n";
		strHeader += "#      Module:" + Module + "\n";
		strHeader += "#        Name:" + Identifier + "\n";
		strHeader += "#  Build Time:" + strTime + "\n";
		strHeader += "#############################################################\n";
		return strHeader;

	}

}
